package com.jsptags.navigation.pager.parser;

import java.io.*;

public final class JavaCharStream {

	public static final boolean staticFlag = false;
	public int bufpos;
	int bufsize;
	int available;
	int tokenBegin;
	private int bufline[];
	private int bufcolumn[];
	private int column;
	private int line;
	private boolean prevCharIsCR;
	private boolean prevCharIsLF;
	private Reader inputStream;
	private char nextCharBuf[];
	private char buffer[];
	private int maxNextCharInd;
	private int nextCharInd;
	private int inBuf;

	static final int hexval(char c) throws IOException {
		switch (c) {
		case 48: // '0'
			return 0;

		case 49: // '1'
			return 1;

		case 50: // '2'
			return 2;

		case 51: // '3'
			return 3;

		case 52: // '4'
			return 4;

		case 53: // '5'
			return 5;

		case 54: // '6'
			return 6;

		case 55: // '7'
			return 7;

		case 56: // '8'
			return 8;

		case 57: // '9'
			return 9;

		case 65: // 'A'
		case 97: // 'a'
			return 10;

		case 66: // 'B'
		case 98: // 'b'
			return 11;

		case 67: // 'C'
		case 99: // 'c'
			return 12;

		case 68: // 'D'
		case 100: // 'd'
			return 13;

		case 69: // 'E'
		case 101: // 'e'
			return 14;

		case 70: // 'F'
		case 102: // 'f'
			return 15;

		case 58: // ':'
		case 59: // ';'
		case 60: // '<'
		case 61: // '='
		case 62: // '>'
		case 63: // '?'
		case 64: // '@'
		case 71: // 'G'
		case 72: // 'H'
		case 73: // 'I'
		case 74: // 'J'
		case 75: // 'K'
		case 76: // 'L'
		case 77: // 'M'
		case 78: // 'N'
		case 79: // 'O'
		case 80: // 'P'
		case 81: // 'Q'
		case 82: // 'R'
		case 83: // 'S'
		case 84: // 'T'
		case 85: // 'U'
		case 86: // 'V'
		case 87: // 'W'
		case 88: // 'X'
		case 89: // 'Y'
		case 90: // 'Z'
		case 91: // '['
		case 92: // '\\'
		case 93: // ']'
		case 94: // '^'
		case 95: // '_'
		case 96: // '`'
		default:
			throw new IOException();
		}
	}

	private final void ExpandBuff(boolean flag) {
		char ac[] = new char[bufsize + 2048];
		int ai[] = new int[bufsize + 2048];
		int ai1[] = new int[bufsize + 2048];
		try {
			if (flag) {
				System.arraycopy(buffer, tokenBegin, ac, 0, bufsize
						- tokenBegin);
				System.arraycopy(buffer, 0, ac, bufsize - tokenBegin, bufpos);
				buffer = ac;
				System.arraycopy(bufline, tokenBegin, ai, 0, bufsize
						- tokenBegin);
				System.arraycopy(bufline, 0, ai, bufsize - tokenBegin, bufpos);
				bufline = ai;
				System.arraycopy(bufcolumn, tokenBegin, ai1, 0, bufsize
						- tokenBegin);
				System.arraycopy(bufcolumn, 0, ai1, bufsize - tokenBegin,
						bufpos);
				bufcolumn = ai1;
				bufpos += bufsize - tokenBegin;
			} else {
				System.arraycopy(buffer, tokenBegin, ac, 0, bufsize
						- tokenBegin);
				buffer = ac;
				System.arraycopy(bufline, tokenBegin, ai, 0, bufsize
						- tokenBegin);
				bufline = ai;
				System.arraycopy(bufcolumn, tokenBegin, ai1, 0, bufsize
						- tokenBegin);
				bufcolumn = ai1;
				bufpos -= tokenBegin;
			}
		} catch (Throwable throwable) {
			throw new Error(throwable.getMessage());
		}
		available = bufsize += 2048;
		tokenBegin = 0;
	}

	private final void FillBuff() throws IOException {
		if (maxNextCharInd == 4096)
			maxNextCharInd = nextCharInd = 0;
		int i;
		try {
			if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
					4096 - maxNextCharInd)) == -1) {
				inputStream.close();
				throw new IOException();
			} else {
				maxNextCharInd += i;
				return;
			}
		} catch (IOException ioexception) {
			if (bufpos != 0) {
				bufpos--;
				backup(0);
			} else {
				bufline[bufpos] = line;
				bufcolumn[bufpos] = column;
			}
			throw ioexception;
		}
	}

	private final char ReadByte() throws IOException {
		if (++nextCharInd >= maxNextCharInd)
			FillBuff();
		return nextCharBuf[nextCharInd];
	}

	public final char BeginToken() throws IOException {
		if (inBuf > 0) {
			inBuf--;
			if (++bufpos == bufsize)
				bufpos = 0;
			tokenBegin = bufpos;
			return buffer[bufpos];
		} else {
			tokenBegin = 0;
			bufpos = -1;
			return readChar();
		}
	}

	private final void AdjustBuffSize() {
		if (available == bufsize) {
			if (tokenBegin > 2048) {
				bufpos = 0;
				available = tokenBegin;
			} else {
				ExpandBuff(false);
			}
		} else if (available > tokenBegin)
			available = bufsize;
		else if (tokenBegin - available < 2048)
			ExpandBuff(true);
		else
			available = tokenBegin;
	}

	private final void UpdateLineColumn(char c) {
		column++;
		if (prevCharIsLF) {
			prevCharIsLF = false;
			line += column = 1;
		} else if (prevCharIsCR) {
			prevCharIsCR = false;
			if (c == '\n')
				prevCharIsLF = true;
			else
				line += column = 1;
		}
		switch (c) {
		case 13: // '\r'
			prevCharIsCR = true;
			break;

		case 10: // '\n'
			prevCharIsLF = true;
			break;

		case 9: // '\t'
			column--;
			column += 8 - (column & 7);
			break;
		}
		bufline[bufpos] = line;
		bufcolumn[bufpos] = column;
	}

	public final char readChar() throws IOException {
		// TODO
		return 0;
	}

	/**
	 * @deprecated Method getColumn is deprecated
	 */

	public final int getColumn() {
		return bufcolumn[bufpos];
	}

	/**
	 * @deprecated Method getLine is deprecated
	 */

	public final int getLine() {
		return bufline[bufpos];
	}

	public final int getEndColumn() {
		return bufcolumn[bufpos];
	}

	public final int getEndLine() {
		return bufline[bufpos];
	}

	public final int getBeginColumn() {
		return bufcolumn[tokenBegin];
	}

	public final int getBeginLine() {
		return bufline[tokenBegin];
	}

	public final void backup(int i) {
		inBuf += i;
		if ((bufpos -= i) < 0)
			bufpos += bufsize;
	}

	public final void ReInit(Reader reader, int i, int j, int k) {
		inputStream = reader;
		line = i;
		column = j - 1;
		if (buffer == null || k != buffer.length) {
			available = bufsize = k;
			buffer = new char[k];
			bufline = new int[k];
			bufcolumn = new int[k];
			nextCharBuf = new char[4096];
		}
		prevCharIsLF = prevCharIsCR = false;
		tokenBegin = inBuf = maxNextCharInd = 0;
		nextCharInd = bufpos = -1;
	}

	public final void ReInit(Reader reader, int i, int j) {
		ReInit(reader, i, j, 4096);
	}

	public final void ReInit(Reader reader) {
		ReInit(reader, 1, 1, 4096);
	}

	public final void ReInit(InputStream inputstream, int i, int j, int k) {
		ReInit(((Reader) (new InputStreamReader(inputstream))), i, j, 4096);
	}

	public final void ReInit(InputStream inputstream, int i, int j) {
		ReInit(inputstream, i, j, 4096);
	}

	public final void ReInit(InputStream inputstream) {
		ReInit(inputstream, 1, 1, 4096);
	}

	public final String GetImage() {
		if (bufpos >= tokenBegin)
			return new String(buffer, tokenBegin, (bufpos - tokenBegin) + 1);
		else
			return new String(buffer, tokenBegin, bufsize - tokenBegin)
					+ new String(buffer, 0, bufpos + 1);
	}

	public final char[] GetSuffix(int i) {
		char ac[] = new char[i];
		if (bufpos + 1 >= i) {
			System.arraycopy(buffer, (bufpos - i) + 1, ac, 0, i);
		} else {
			System.arraycopy(buffer, bufsize - (i - bufpos - 1), ac, 0, i
					- bufpos - 1);
			System.arraycopy(buffer, 0, ac, i - bufpos - 1, bufpos + 1);
		}
		return ac;
	}

	public final void Done() {
		nextCharBuf = null;
		buffer = null;
		bufline = null;
		bufcolumn = null;
	}

	public final void adjustBeginLineColumn(int i, int j) {
		int k = tokenBegin;
		int l;
		if (bufpos >= tokenBegin)
			l = (bufpos - tokenBegin) + inBuf + 1;
		else
			l = (bufsize - tokenBegin) + bufpos + 1 + inBuf;
		int i1 = 0;
		int j1 = 0;
		boolean flag = false;
		boolean flag1 = false;
		int i2 = 0;
		int k1;
		for (; i1 < l
				&& bufline[j1 = k % bufsize] == bufline[k1 = ++k % bufsize]; i1++) {
			bufline[j1] = i;
			int l1 = (i2 + bufcolumn[k1]) - bufcolumn[j1];
			bufcolumn[j1] = j + i2;
			i2 = l1;
		}

		if (i1 < l) {
			bufline[j1] = i++;
			bufcolumn[j1] = j + i2;
			while (i1++ < l)
				if (bufline[j1 = k % bufsize] != bufline[++k % bufsize])
					bufline[j1] = i++;
				else
					bufline[j1] = i;
		}
		line = bufline[j1];
		column = bufcolumn[j1];
	}

	public JavaCharStream(Reader reader, int i, int j, int k) {
		bufpos = -1;
		column = 0;
		line = 1;
		prevCharIsCR = false;
		prevCharIsLF = false;
		maxNextCharInd = 0;
		nextCharInd = -1;
		inBuf = 0;
		inputStream = reader;
		line = i;
		column = j - 1;
		available = bufsize = k;
		buffer = new char[k];
		bufline = new int[k];
		bufcolumn = new int[k];
		nextCharBuf = new char[4096];
	}

	public JavaCharStream(Reader reader, int i, int j) {
		this(reader, i, j, 4096);
	}

	public JavaCharStream(Reader reader) {
		this(reader, 1, 1, 4096);
	}

	public JavaCharStream(InputStream inputstream, int i, int j, int k) {
		this(((Reader) (new InputStreamReader(inputstream))), i, j, 4096);
	}

	public JavaCharStream(InputStream inputstream, int i, int j) {
		this(inputstream, i, j, 4096);
	}

	public JavaCharStream(InputStream inputstream) {
		this(inputstream, 1, 1, 4096);
	}
}
